﻿using AutoIt;
using AutoUpdaterDotNET;
using dTools;
using dTools.Extensions;
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Demo.PTGUI
{
    public partial class FrmMain : Form
    {
        QueueHelper<(Color Color, string msg)> queue = new QueueHelper<(Color Color, string msg)>();

        public FrmMain()
        {
            InitializeComponent();
        }

        #region 禁用
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x112)
            {
                switch ((int)m.WParam)
                {
                    //禁止双击标题栏关闭窗体
                    case 0xF063:
                    case 0xF093:
                        m.WParam = IntPtr.Zero;
                        break;

                    //禁止拖拽标题栏还原窗体
                    case 0xF012:
                    case 0xF010:
                        m.WParam = IntPtr.Zero;
                        break;

                    //禁止双击标题栏
                    case 0xf122:
                        m.WParam = IntPtr.Zero;
                        break;

                    //禁止关闭按钮
                    //case 0xF060:
                    //    m.WParam = IntPtr.Zero;
                    //    break;

                    //禁止最大化按钮
                    //case 0xf020:
                    //    //if (GetTaskCount() > 0)
                    //    //{
                    //    //    m.WParam = IntPtr.Zero;
                    //    //    MessageBox.Show("程序默认最大化,无法最小化1");
                    //    //}
                    //    m.WParam = IntPtr.Zero;
                    //    MessageBox.Show("程序默认最大化,无法最小化1");
                    //    break;

                    //禁止最小化按钮
                    case 0xf030:
                        //if (GetTaskCount() > 0 && cbNotMove.Checked)
                        //{



                        //    m.WParam = IntPtr.Zero;
                        //    MessageBox.Show("存在待处理的任务,无法最小化");
                        //}
                        //m.WParam = IntPtr.Zero;
                        //MessageBox.Show("程序默认最大化,无法最小化2");
                        break;

                    //禁止还原按钮
                    case 0xf120:
                        //m.WParam = IntPtr.Zero;
                        break;
                }
            }
            base.WndProc(ref m);
        }
        #endregion
        private void FrmMain_Load(object sender, EventArgs e)
        {
            var hwnd = FindHandle("PTGui");
            if (hwnd > 0)
            {
                AutoItX.WinClose((IntPtr)hwnd);
                AutoItX.ControlClick("PTGui Pro", "", "Button3", "left", 1);
            }

            this.MaximizedBounds = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea;
            queue.DealAction = _ =>
            {
                if (txtLog.InvokeRequired)
                {
                    txtLog.BeginInvoke(new Action(() =>
                    {
                        txtLog.Write(_.msg, _.Color);
                    }));
                }
                else
                {
                    txtLog.Write(_.msg, _.Color);
                }
            };

            //左下
            var screen = Screen.FromPoint(new Point(Cursor.Position.X, Cursor.Position.Y));
            var x = 0;
            var y = screen.WorkingArea.Y + screen.WorkingArea.Height - this.Height;
            /*
             * 右下
              var x = screen.WorkingArea.X + screen.WorkingArea.Width - this.Width;
              var y = screen.WorkingArea.Y + screen.WorkingArea.Height - this.Height;
             */
            this.Location = new Point(x, y);
            btnTryRunPTGUI_Click(null, null);

            #region 检查更新
            AutoUpdater.RunUpdateAsAdmin = true;
            AutoUpdater.InstallationPath = Environment.CurrentDirectory;
            AutoUpdater.CheckForUpdateEvent += AutoUpdaterOnCheckForUpdateEvent;
            AutoUpdater.ApplicationExitEvent += AutoUpdater_ApplicationExitEvent;
            #endregion
        }

        readonly string titleDefault = "未命名 - PTGui Pro 注册给 John Scott";
        readonly string titleChange = "未命名 * - PTGui Pro 注册给 John Scott";

        private void btnTryRunPTGUI_Click(object sender, EventArgs e)
        {
            btnTryRunPTGUI.Enabled = false;
            btnTryRunPTGUI.Text = "运行中...";

            //创建任务
            Task.Run(async () =>
            {
                while (true)
                {
                    Config config = EasyConf.Read<Config>();
                    var check = CheckParamater(config);
                    if (check == "OK")
                    {
                        var allFiles = FileHelper.GetFiles(config.MonitorImagePath).OrderBy(x => x.LastWriteTime).ToList();
                        DateTime create = DateTime.Now;
                        if (allFiles.Count == 1)
                        {
                            if ((DateTime.Now - allFiles[0].LastWriteTime).TotalSeconds >= config.DiffSec)
                            {
                                //Move
                                var taskPath = FileHelper.Combine(AppDomain.CurrentDomain.BaseDirectory, "Tasks", $"S_{DateTime.Now:yyyyMMdd_HHmmss}");
                                File.Move(allFiles[0].FullName, Path.Combine(taskPath, allFiles[0].Name));
                            }
                        }
                        else
                        {
                            for (int i = 0; i < allFiles.Count; i++)
                            {
                                var f = allFiles[i];
                                var nDate = DateTime.Now;
                                var fDate = f.LastWriteTime;

                                //最后一组
                                if (i == allFiles.Count - 1)
                                {
                                    //当前时间
                                    nDate = DateTime.Now;
                                }
                                else
                                {
                                    //不是最后一组
                                    var n = allFiles[i + 1];
                                    nDate = n.LastWriteTime;
                                }

                                if ((nDate - fDate).TotalSeconds > config.DiffSec)
                                {
                                    //Move
                                    var taskPath = FileHelper.Combine(AppDomain.CurrentDomain.BaseDirectory, "Tasks", $"{DateTime.Now:yyyyMMdd_HHmmss}");
                                    allFiles.Where(x => x.LastWriteTime < nDate).ToList()
                                    .ForEach(x =>
                                    {
                                        File.Move(x.FullName, Path.Combine(taskPath, x.Name));
                                    });
                                    break;
                                }
                            }
                        }
                        await Task.Delay(300);
                    }
                    else
                    {
                        await Task.Delay(800);
                    }
                }
            });

            //处理任务
            Task.Run(async () =>
            {
                while (true)
                {
                    Config config = EasyConf.Read<Config>();
                    var check = CheckParamater(config);
                    if (check == "OK")
                    {
                        try
                        {
                            await LoadPic(config);
                        }
                        catch (Exception ex)
                        {
                            Sys.Log($"Process Task:{ex.Message}");
                        }
                    }
                    else
                    {
                        queue.Enqueue((Color.Red, check));
                        await Task.Delay(1000 * 10);
                    }
                }
            });
        }

        private async Task LoadPic(Config config)
        {
            var taskDir = FileHelper.Combine(AppDomain.CurrentDomain.BaseDirectory, "Tasks");
            var taskPaths = new DirectoryInfo(taskDir).GetDirectories();
            if (taskPaths.Count() > 0)
            {
                var directoryInfo = taskPaths[0];
                var sourceFile = directoryInfo.FullName;
                if (FileHelper.GetFiles(sourceFile).Count > 0)
                {
                    var hwnd = FindHandle("PTGui");
                    if (hwnd > 0)
                    {
                        AutoItX.WinClose((IntPtr)hwnd);
                        AutoItX.ControlClick("PTGui Pro", "", "Button3", "left", 1);
                        await Task.Delay(3000);//保证软件退干净
                    }
                    Process.Start(config.PTGuiPath);
                    //隐藏PTGUI启动页面
                    while (AutoItX.WinGetState("[CLASS:wxWindowNR; INSTANCE:1]", "") != 13)
                    {
                        AutoItX.WinSetState("[CLASS:wxWindowNR; INSTANCE:1]", "", 0);
                        await Task.Delay(10);
                    }
                    queue.Enqueue((Color.Green, "启动PTGUI完成"));

                    hwnd = FindHandle("PTGui");
                    while (hwnd <= 0)
                    {
                        hwnd = FindHandle("PTGui");
                        await Task.Delay(100);
                    }

                    AutoItX.WinMove((IntPtr)hwnd, 0, 0);

                    //尝试关闭编辑器
                    TryCloseEdit();

                    //点击加载图像
                    await LoadImageAsync(sourceFile);
                    queue.Enqueue((Color.Green, "加载图像完成"));

                    //尝试关闭编辑器
                    TryCloseEdit();

                    //对准图像
                    AutoItX.ControlClick(titleChange, "", "Button6", "left", 1);
                    await Task.Delay(1000);
                    await WaitWindowCloseAsync();
                    queue.Enqueue((Color.Green, "对准图像完成"));

                    // 全景图编辑器圆柱体
                    await Click圆柱();

                    //点击创建全景图选项卡 & 创建全景图
                    AutoItX.ControlClick(titleChange, "", "Button7", "left", 2);

                    //判断是否选择TIFF
                    string outFile = Path.Combine(config.SaveImagePath, directoryInfo.Name + Guid.NewGuid().ToString().Replace("-", "").ToUpper().Substring(0, 6) + ".jpg");
                    if (UseTIFF(sourceFile))
                    {
                        AutoItX.ControlCommand(titleChange, "", "ComboBox17", "SelectString", "TIFF(.tif)");
                        outFile = Path.Combine(config.SaveImagePath, directoryInfo.Name + ".tif");
                    }
                    AutoItX.ControlSetText(titleChange, "", "Edit36", outFile);

                    //点击创建全景图
                    AutoItX.ControlClick(titleChange, "", "Button100", "left", 1);
                    await WaitWindowCloseAsync();
                    queue.Enqueue((Color.Green, "创建全景图完成,开始清理残留信息.."));

                    //预览合成后的全景图
                    _ = Task.Run(() =>
                    {
                        if (File.Exists(outFile))
                        {
                            try
                            {
                                using (var fs = new FileStream(outFile, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                                {
                                    Image image = Image.FromStream(fs);
                                    picShow.InvokeExt(new Action(() => { picShow.Image = image; }));
                                }
                            }
                            catch (Exception ex)
                            {
                                Sys.Log($"show image error:{ex.Message}");
                                picShow.InvokeExt(new Action(() => { picShow.Image = null; }));
                            }
                        }
                    });

                    AutoItX.WinClose(titleChange);

                    AutoItX.ControlClick("PTGui Pro", "", "Button3", "left", 1);

                    queue.Enqueue((Color.Green, "清理残留信息完成，等待新照片生成中"));

                    //备份图片
                    var allFile = FileHelper.GetFiles(sourceFile);
                    try
                    {
                        foreach (var item in allFile)
                        {
                            var destFile = Path.Combine(config.SingleBackImagePath, item.Name);
                            if (File.Exists(destFile))
                            {
                                File.Delete(destFile);
                            }
                            File.Move(item.FullName, destFile);
                        }
                    }
                    catch (Exception ex)
                    {
                        Sys.Log($"back file Error:{ex.Message}");
                    }
                }
                //删除任务
                Directory.Delete(sourceFile);
            }
            else
            {
                await Task.Delay(1000);
            }
        }


        private int FindHandle(string processName)
        {
            int handle = 0;
            foreach (var process in Process.GetProcesses())
            {
                if (process.ProcessName == processName)
                {
                    if (handle == 0)
                    {
                        handle = (int)process.MainWindowHandle;
                        //Console.WriteLine($"{process.ProcessName},{process.MainWindowHandle},{process.MainWindowTitle}");
                    }
                    else
                    {
                        process.Kill();
                    }
                }
            }
            return handle;
        }


        private bool UseTIFF(string path)
        {
            var totalWidth = 0;
            var totalHeight = 0;

            new DirectoryInfo(path).GetFiles().ToList().ForEach(file =>
            {
                using (Stream stream = File.OpenRead(file.FullName))
                {
                    using (Image sourceImage = Image.FromStream(stream, false, false))
                    {
                        totalWidth += sourceImage.Width;
                        totalHeight += sourceImage.Height;
                    }
                }
            });
            return totalHeight > 30000;
        }

        private string CheckParamater(Config config)
        {
            if (!File.Exists(config.PTGuiPath))
                return $"PTGui程序不存在或者路径配置错误";

            if (!Directory.Exists(config.MonitorImagePath))
                return $"监控路径不存在";

            if (!Directory.Exists(config.SingleBackImagePath))
                return $"单片备份路径不存在";

            if (!Directory.Exists(config.SaveImagePath))
                return $"成片保存路径不存在";


            if (config.SingleBackImagePath == config.MonitorImagePath)
            {
                return "备份路径不能和监控路径一致";
            }
            return "OK";
        }

        /// <summary>
        /// 加载图片
        /// </summary>
        private async Task LoadImageAsync(string sourceFile)
        {
            while (true)
            {
                var click = AutoItX.ControlClick(titleDefault, "", "Button1", "left", 1) > 0;
                if (click)
                    break;
            }

            while (true)
            {
                var hw = AutoItX.WinGetState("添加图像", "");
                if (hw > 0)
                    break;
                //Console.WriteLine($"添加图像框是否弹出来:{hw}");
                await Task.Delay(100);
            }
            //选择文件
            AutoItOperation.SelectAllFiles("添加图像", sourceFile, 300);
        }

        private void TryCloseEdit()
        {
            // 如果找到全景图编辑器,尝试关闭
            if (!string.IsNullOrEmpty(AutoItX.ControlGetText("全景图编辑器", "", "Button1")))
                AutoItX.WinClose("全景图编辑器");
        }

        private async Task Click圆柱()
        {
            while (true)
            {
                if (!string.IsNullOrEmpty(AutoItX.ControlGetText("全景图编辑器", "", "Button1")))
                    break;
                await Task.Delay(100);
            }

            AutoItX.ControlFocus("全景图编辑器", "", "ToolbarWindow321");
            SendKeys.SendWait("^%c");
            AutoItX.WinClose("全景图编辑器");
            await Task.Delay(100);
        }

        /// <summary>
        /// 检查某些window是否关闭
        /// </summary>
        /// <returns></returns>
        private async Task WaitWindowCloseAsync(string title = "请稍候...", int appendWait = 0)
        {
            while (true)
            {
                await Task.Delay(100);
                var hw = AutoItX.WinGetState(title, "");
                //Console.WriteLine($"检查某些window是否关闭:{hw}");
                if (hw <= 0)
                    break;
            }
            if (appendWait > 0)
            {
                await Task.Delay(appendWait);
            }
        }

        private void btnSetting_Click(object sender, EventArgs e)
        {
            new FrmSetting().ShowDialog();
        }

        private void btnRestart_Click(object sender, EventArgs e)
        {
            Application.Restart();
        }

        private void timerTask_Tick(object sender, EventArgs e)
        {
            var taskCount = GetTaskCount();
            if (taskCount > 0 && cbNotMove.Checked)
                WindowState = FormWindowState.Maximized;
            lblTask.Text = $"{taskCount}";
        }

        private int GetTaskCount()
        {
            try
            {
                var taskDir = FileHelper.Combine(AppDomain.CurrentDomain.BaseDirectory, "Tasks");
                var taskPaths = new DirectoryInfo(taskDir).GetDirectories();
                foreach (var item in taskPaths)
                {
                    if (item.GetFiles().Count() == 0)
                        Directory.Delete(item.FullName);
                }
                return new DirectoryInfo(taskDir).GetDirectories().Count();
            }
            catch (Exception)
            {
                return -1;
            }
        }

        private void lblTask_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            var taskDir = FileHelper.Combine(AppDomain.CurrentDomain.BaseDirectory, "Tasks");
            Process.Start(taskDir);
        }

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            //System.Environment.Exit(0);
        }

        private void btnCheckUpdate_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            AutoUpdater.Start("http://47.103.148.154:8005/JieTu2.0/AutoUpdater.xml");
        }
        private void AutoUpdaterOnCheckForUpdateEvent(UpdateInfoEventArgs args)
        {
            try
            {
                if (args.IsUpdateAvailable && AutoUpdater.DownloadUpdate(args))
                {
                    Application.Exit();
                }
            }
            catch { }
        }
        private void AutoUpdater_ApplicationExitEvent()
        {
            Environment.Exit(0);
        }
    }
}
